package pers.cz.jefautoscreen;

import com.tulskiy.keymaster.common.Provider;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.apache.commons.io.FileUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;

public class SmartScreenshotController extends JFrame {
	private JTextField startXField, startYField, width, hight;
	private JTextField dragStartXField, dragStartYField, dragEndXField, dragEndYField;
	private JTextField screenshotCountField, intervalField, startNumberField, filePathField;
	private JTextField targetLanguageField, llmPathField, resultPathField, imageStartField, imageEndField;
	private JTextArea logArea;
	private JButton startButton, stopButton, testButton;
	private ScheduledExecutorService executor;
	private volatile boolean isRunning = false;
	private int currentCount = 0;
	private int startNumber = 0;
	private Robot robot;

	public SmartScreenshotController() {
		try {
			robot = new Robot();
			robot.setAutoDelay(100);
		} catch (AWTException e) {
			e.printStackTrace();
		}

		initializeUI();
	}

	private void initializeUI() {
		setTitle("智能截图控制器 - 电子书翻页工具");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(500, 1050); // 稍微增加高度
		setLocationRelativeTo(null);

		// 主面板
		JPanel mainPanel = new JPanel(new BorderLayout());

		// 顶部标题
		JLabel titleLabel = new JLabel("智能截图控制器", SwingConstants.CENTER);
		titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
		titleLabel.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0));
		mainPanel.add(titleLabel, BorderLayout.NORTH);

		// 中央控制面板
		JPanel controlPanel = createControlPanel();
		mainPanel.add(controlPanel, BorderLayout.CENTER);

		// 底部日志区域
		JPanel logPanel = createLogPanel();
		mainPanel.add(logPanel, BorderLayout.SOUTH);

		setContentPane(mainPanel);
	}

	private JPanel createControlPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.insets = new Insets(5, 5, 5, 5);
		gbc.anchor = GridBagConstraints.WEST;

		// 截图区域设置
		gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2;
		panel.add(createScreenshotAreaPanel(), gbc);

		// 鼠标设置
		gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2;
		panel.add(createDragAreaPanel(), gbc);

		// 控制参数
		gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 2;
		panel.add(createControlParamsPanel(), gbc);

		// 操作按钮
		gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 2;
		panel.add(createButtonPanel(), gbc);

		// ocr识别区
		gbc.gridx = 0; gbc.gridy = 4; gbc.gridwidth = 2;
		panel.add(createOcrPanel(), gbc);

		return panel;
	}

	private JPanel createScreenshotAreaPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder("截图区域设置"));

		JPanel inputPanel = new JPanel(new GridLayout(2, 4, 10, 5));

		startXField = new JTextField("0");
		startYField = new JTextField("85");
		width = new JTextField("580");
		hight = new JTextField("980");

		inputPanel.add(new JLabel("起始X:"));
		inputPanel.add(startXField);
		inputPanel.add(new JLabel("起始Y:"));
		inputPanel.add(startYField);
		inputPanel.add(new JLabel("宽:"));
		inputPanel.add(width);
		inputPanel.add(new JLabel("高:"));
		inputPanel.add(hight);

		JButton captureAreaButton = new JButton("获取屏幕区域");
		captureAreaButton.addActionListener(e -> captureScreenArea());

		panel.add(inputPanel, BorderLayout.CENTER);
		panel.add(captureAreaButton, BorderLayout.SOUTH);

		return panel;
	}

	private JPanel createDragAreaPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder("鼠标设置（翻页）"));

		JPanel inputPanel = new JPanel(new GridLayout(2, 4, 10, 5));

		dragStartXField = new JTextField("522");
		dragStartYField = new JTextField("326");
		dragEndXField = new JTextField("58");
		dragEndYField = new JTextField("326");

		inputPanel.add(new JLabel("鼠标起始X:"));
		inputPanel.add(dragStartXField);
		inputPanel.add(new JLabel("鼠标起始Y:"));
		inputPanel.add(dragStartYField);
		inputPanel.add(new JLabel("鼠标结束X:"));
		inputPanel.add(dragEndXField);
		inputPanel.add(new JLabel("鼠标结束Y:"));
		inputPanel.add(dragEndYField);

		JButton testDragButton = new JButton("测试鼠标");
		testDragButton.addActionListener(e -> testDrag());

		panel.add(inputPanel, BorderLayout.CENTER);
		panel.add(testDragButton, BorderLayout.SOUTH);

		return panel;
	}

	private JPanel createControlParamsPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder("控制参数"));

		// 修改为3行布局以容纳新的起始编号字段
		JPanel inputPanel = new JPanel(new GridLayout(5, 3, 10, 5));

		screenshotCountField = new JTextField("10");
		intervalField = new JTextField("2000");
		startNumberField = new JTextField("0"); // 新增起始编号字段
		filePathField = new JTextField("D:\\temp");

		inputPanel.add(new JLabel("截图次数:"));
		inputPanel.add(screenshotCountField);
		inputPanel.add(new JLabel("间隔时间(毫秒):"));
		inputPanel.add(intervalField);
		inputPanel.add(new JLabel("起始编号:"));
		inputPanel.add(startNumberField);
		inputPanel.add(new JLabel("文件保存路径："));
		inputPanel.add(filePathField);
		inputPanel.add(new JLabel(""));
		inputPanel.add(new JLabel(""));

		// 添加编号预览和重置按钮
		JPanel buttonPanel = new JPanel(new FlowLayout());
		JButton previewNumberButton = new JButton("预览编号");
		JButton resetNumberButton = new JButton("重置编号");

		previewNumberButton.addActionListener(e -> previewNumbering());
		resetNumberButton.addActionListener(e -> resetNumbering());

		buttonPanel.add(previewNumberButton);
		buttonPanel.add(resetNumberButton);

		panel.add(inputPanel, BorderLayout.CENTER);
		panel.add(buttonPanel, BorderLayout.SOUTH);

		return panel;
	}

	private JPanel createOcrPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder("Ocr识别"));

		JPanel inputPanel = new JPanel(new GridLayout(6, 3, 10, 5));

		targetLanguageField = new JTextField("tur");
		llmPathField = new JTextField("D:\\java\\ocr\\tessdata");
		resultPathField = new JTextField("D:\\logs\\ocr\\result.txt");
		imageStartField = new JTextField("0");
		imageEndField = new JTextField("10");

		inputPanel.add(new JLabel("目标语言:"));
		inputPanel.add(targetLanguageField);
		inputPanel.add(new JLabel("模型路径："));
		inputPanel.add(llmPathField);
		inputPanel.add(new JLabel("结果路径："));
		inputPanel.add(resultPathField);
		inputPanel.add(new JLabel("图片起始编号："));
		inputPanel.add(imageStartField);
		inputPanel.add(new JLabel("图片结束编号："));
		inputPanel.add(imageEndField);
		inputPanel.add(new JLabel(""));
		inputPanel.add(new JLabel(""));

		// 添加编号预览和重置按钮
		JPanel buttonPanel = new JPanel(new FlowLayout());
		JButton discernButton = new JButton("开始识别");

		discernButton.addActionListener(e -> startDiscern());

		buttonPanel.add(discernButton);

		panel.add(inputPanel, BorderLayout.CENTER);
		panel.add(buttonPanel, BorderLayout.SOUTH);

		return panel;
	}

	private JPanel createButtonPanel() {
		JPanel panel = new JPanel(new FlowLayout());

		startButton = new JButton("开始自动截图");
		stopButton = new JButton("停止（Ctrl+ D）");
		testButton = new JButton("测试截图");
		JButton previewButton = new JButton("预览截图区域");

		startButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
		stopButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
		testButton.setFont(new Font("微软雅黑", Font.BOLD, 14));

		startButton.setBackground(Color.GREEN);
		stopButton.setBackground(Color.RED);
		stopButton.setEnabled(false);

		startButton.addActionListener(e -> startAutoScreenshot());
		stopButton.addActionListener(e -> stopAutoScreenshot());
		testButton.addActionListener(e -> testScreenshot());
		previewButton.addActionListener(e -> previewScreenshotArea());

		panel.add(startButton);
		panel.add(stopButton);
		panel.add(testButton);
		panel.add(previewButton);

		return panel;
	}

	private JPanel createLogPanel() {
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createTitledBorder("操作日志"));

		logArea = new JTextArea(10, 50);
		logArea.setEditable(false);
		logArea.setFont(new Font("微软雅黑", Font.PLAIN, 12));

		JScrollPane scrollPane = new JScrollPane(logArea);
		panel.add(scrollPane, BorderLayout.CENTER);

		JButton clearLogButton = new JButton("清空日志");
		clearLogButton.addActionListener(e -> logArea.setText(""));
		panel.add(clearLogButton, BorderLayout.SOUTH);

		return panel;
	}

	// 新增：预览编号功能
	private void previewNumbering() {
		try {
			int startNum = Integer.parseInt(startNumberField.getText());
			int count = Integer.parseInt(screenshotCountField.getText());

			StringBuilder preview = new StringBuilder();
			preview.append("编号预览:\n");

			for (int i = 0; i < Math.min(count, 10); i++) { // 最多预览10个
				int currentNumber = startNum + i;
				String fileName = String.format("screenshot_%04d.png", currentNumber);
				preview.append(String.format("第%d张: %s\n", i + 1, fileName));
			}

			if (count > 10) {
				preview.append("...\n");
				int lastNumber = startNum + count - 1;
				String lastFileName = String.format("screenshot_%04d.png", lastNumber);
				preview.append(String.format("第%d张: %s\n", count, lastFileName));
			}

			JOptionPane.showMessageDialog(this, preview.toString(), "编号预览", JOptionPane.INFORMATION_MESSAGE);
			logMessage(String.format("编号预览: 从 %d 开始，共 %d 张", startNum, count));

		} catch (NumberFormatException ex) {
			logMessage("错误: 请输入有效的起始编号和截图次数");
		}
	}

	// orc识别功能
	private void startDiscern() {
		ITesseract tesseract = new Tesseract();
		// 模型存储路径
		tesseract.setDatapath(llmPathField.getText());
		// 设置需要识别的语言
		tesseract.setLanguage(targetLanguageField.getText());
		int imgStart = Integer.parseInt(imageStartField.getText());
		int imgEnd = Integer.parseInt(imageEndField.getText());

		for (int i = imgStart; i < imgEnd; i++) {
			try {
				String fileName = String.format("screenshot_%04d.png", i);
				logMessage("开始识别: " + fileName);
				File file = new File(getFullFileName() + fileName);
				BufferedImage image = ImageIO.read(file);
				String result = tesseract.doOCR(image);
				// 写入到文件
				FileUtils.writeStringToFile(new File(resultPathField.getText()), result+"\n", StandardCharsets.UTF_8, true);
				logMessage("当前图片识别完成: " + fileName);
			} catch (IOException | TesseractException e) {
				logMessage("图片识别异常：" + e.getMessage());
			}
		}
	}

	// 重置编号功能
	private void resetNumbering() {
		startNumberField.setText("0");
		logMessage("起始编号已重置为 0");
	}

	private void captureScreenArea() {
		logMessage("请在3秒后点击并鼠标选择截图区域...");

		Timer timer = new Timer(3000, e -> {
			// 隐藏窗口
			setVisible(false);

			// 创建全屏透明窗口用于选择区域
			JFrame selectionFrame = new JFrame();
			selectionFrame.setUndecorated(true);
			selectionFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
			selectionFrame.setAlwaysOnTop(true);
			selectionFrame.setBackground(new Color(0, 0, 0, 50));

			AreaSelectionPanel selectionPanel = new AreaSelectionPanel(selectionFrame, this);
			selectionFrame.add(selectionPanel);
			selectionFrame.setVisible(true);
		});
		timer.setRepeats(false);
		timer.start();
	}

	private void testDrag() {
		try {
			int startX = Integer.parseInt(dragStartXField.getText());
			int startY = Integer.parseInt(dragStartYField.getText());
			int endX = Integer.parseInt(dragEndXField.getText());
			int endY = Integer.parseInt(dragEndYField.getText());

			logMessage("开始测试鼠标...");
			performDrag(startX, startY, endX, endY);
			logMessage("鼠标测试完成");
		} catch (NumberFormatException ex) {
			logMessage("错误: 请输入有效的数字");
		}
	}

	private void testScreenshot() {
		try {
			int x = Integer.parseInt(startXField.getText());
			int y = Integer.parseInt(startYField.getText());
			int width = Integer.parseInt(this.width.getText());
			int height = Integer.parseInt(this.hight.getText());
			int startNum = Integer.parseInt(startNumberField.getText());

			Rectangle area = new Rectangle(x, y, width, height);
			BufferedImage screenshot = robot.createScreenCapture(area);

			// 使用编号格式保存测试截图
			String fileName = String.format("test_screenshot_%04d.png", startNum);
			File file = new File(fileName);
			ImageIO.write(screenshot, "png", file);

			logMessage("测试截图已保存: " + file.getPath());
		} catch (Exception ex) {
			logMessage("截图失败: " + ex.getMessage());
		}
	}

	private void previewScreenshotArea() {
		try {
			int x = Integer.parseInt(startXField.getText());
			int y = Integer.parseInt(startYField.getText());
			int width = Integer.parseInt(this.width.getText());
			int height = Integer.parseInt(this.hight.getText());
			int startNum = Integer.parseInt(startNumberField.getText());

			// 创建预览窗口
			JFrame previewFrame = new JFrame("截图区域预览");
			previewFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			previewFrame.setSize(350, 250);
			previewFrame.setLocationRelativeTo(this);

			JLabel infoLabel = new JLabel(String.format(
					"<html><center>截图区域:<br>起始点: (%d, %d)<br>尺寸: %d x %d<br>结束点: (%d, %d)<br><br>编号设置:<br>起始编号: %d<br>文件格式: screenshot_%%04d.png</center></html>",
					x, y, width, height, x + width, y + height, startNum));
			infoLabel.setHorizontalAlignment(SwingConstants.CENTER);

			previewFrame.add(infoLabel);
			previewFrame.setVisible(true);

			logMessage(String.format("预览截图区域: (%d,%d) 尺寸: %dx%d, 起始编号: %d", x, y, width, height, startNum));
		} catch (NumberFormatException ex) {
			logMessage("错误: 请输入有效的坐标数字和起始编号");
		}
	}

	private void startAutoScreenshot() {
		try {
			int count = Integer.parseInt(screenshotCountField.getText());
			int interval = Integer.parseInt(intervalField.getText());
			startNumber = Integer.parseInt(startNumberField.getText()); // 获取起始编号

			if (count <= 0 || interval <= 0) {
				logMessage("错误: 截图次数和间隔时间必须大于0");
				return;
			}

			if (startNumber < 0) {
				logMessage("错误: 起始编号不能为负数");
				return;
			}

			isRunning = true;
			currentCount = 0;
			startButton.setEnabled(false);
			stopButton.setEnabled(true);

			logMessage(String.format("开始自动截图，总计: %d 次，间隔: %d 毫秒，起始编号: %d", count, interval, startNumber));

			executor = Executors.newSingleThreadScheduledExecutor();
			executor.scheduleAtFixedRate(this::performScreenshotAndDrag, 0, interval, TimeUnit.MILLISECONDS);

		} catch (NumberFormatException ex) {
			logMessage("错误: 请输入有效的数字");
		}
	}

	private void stopAutoScreenshot() {
		isRunning = false;
		if (executor != null) {
			executor.shutdown();
		}

		startButton.setEnabled(true);
		stopButton.setEnabled(false);

		logMessage(String.format("自动截图已停止，共完成: %d 次，最后编号: %d", currentCount, startNumber + currentCount - 1));
	}

	private void performScreenshotAndDrag() {
		if (!isRunning) return;

		try {

			// 检查是否完成
			int totalCount = Integer.parseInt(screenshotCountField.getText());
			if (currentCount >= totalCount) {
				SwingUtilities.invokeLater(this::stopAutoScreenshot);
				return;
			}

			// 执行截图
			int x = Integer.parseInt(startXField.getText());
			int y = Integer.parseInt(startYField.getText());
			int width = Integer.parseInt(this.width.getText());
			int height = Integer.parseInt(this.hight.getText());
			Rectangle area = new Rectangle(x, y, width, height);
			BufferedImage screenshot = robot.createScreenCapture(area);

			// 使用编号格式保存截图
			int currentNumber = startNumber + currentCount;
			String fileName = String.format("screenshot_%04d.png", currentNumber);
			File file = new File(getFullFileName() + fileName);
			ImageIO.write(screenshot, "png", file);

			currentCount++;
			logMessage(String.format("截图 %d 已保存: %s (编号: %04d)", currentCount, fileName, currentNumber));

			// 执行鼠标翻页
			Thread.sleep(200); // 短暂延迟
			int startX = Integer.parseInt(dragStartXField.getText());
			int startY = Integer.parseInt(dragStartYField.getText());
			int endX = Integer.parseInt(dragEndXField.getText());
			int endY = Integer.parseInt(dragEndYField.getText());

			performDrag(startX, startY, endX, endY);
			Thread.sleep(200); // 等待翻过去
		} catch (Exception ex) {
			SwingUtilities.invokeLater(() -> {
				logMessage("执行失败: " + ex.getMessage());
				stopAutoScreenshot();
			});
		}
	}

	private String getFullFileName() {
		String filePath = filePathField.getText();
		if (!filePath.endsWith("\\")) {
			filePath = filePath + "\\";
		}
		return filePath;
	}
	private void performDrag(int startX, int startY, int endX, int endY) {

		try {
			Robot myRobot = new Robot();
			// 移动到起始位置
			myRobot.mouseMove(startX, startY);
			Thread.sleep(100);

			// 按下鼠标
			myRobot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
			Thread.sleep(50);

			// 分步鼠标，模拟真实鼠标效果
			int steps = 20;
			for (int i = 1; i <= steps; i++) {
				int currentX = startX + (endX - startX) * i / steps;
				int currentY = startY + (endY - startY) * i / steps;
				myRobot.mouseMove(currentX, currentY);
				Thread.sleep(10);
			}

			// 释放鼠标
			myRobot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
			Thread.sleep(100);

		} catch (InterruptedException | AWTException ex) {
			Thread.currentThread().interrupt();
		}
	}

	public void setScreenshotArea(int x, int y, int width, int height) {
		startXField.setText(String.valueOf(x));
		startYField.setText(String.valueOf(y));
		this.width.setText(String.valueOf(width));
		this.hight.setText(String.valueOf(height));
		logMessage(String.format("截图区域已设置: (%d,%d) 尺寸: %dx%d", x, y, width, height));
	}

	private void logMessage(String message) {
		SwingUtilities.invokeLater(() -> {
			String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date());
			logArea.append(String.format("[%s] %s\n", timestamp, message));
			logArea.setCaretPosition(logArea.getDocument().getLength());
		});
	}

	private static TrayIcon trayIcon;

	private static final String ICON_PATH = "auto.png";

	public static void main(String[] args) {

		SwingUtilities.invokeLater(() -> {
			SmartScreenshotController smartScreenshotController = new SmartScreenshotController();
			smartScreenshotController.setVisible(true);

			// 绑定快捷键
			Provider provider = Provider.getCurrentProvider(true);
			provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
					x-> smartScreenshotController.stopAutoScreenshot());
		});

		PopupMenu popupMenu = new PopupMenu();
		MenuItem exitItem = new MenuItem("exit");

		popupMenu.add(exitItem);

		Image normalImage = Toolkit.getDefaultToolkit().getImage(SmartScreenshotController.class.getClassLoader().getResource(ICON_PATH));
		trayIcon = new TrayIcon(normalImage, "自动截图工具", popupMenu);
		trayIcon.setImageAutoSize(true);
		trayIcon.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON1) {
					JOptionPane.showMessageDialog(null, "自动截图工具正在运行中,如需关闭请右击托盘...");
				}
			}
		});

		try {
			SystemTray.getSystemTray().add(trayIcon);
			exitItem.addActionListener(e -> {
				SystemTray.getSystemTray().remove(trayIcon);
				System.exit(0);
			});
		} catch (AWTException e) {
			e.printStackTrace();
		}

	}
}

// 区域选择面板保持不变
class AreaSelectionPanel extends JPanel {
	private Point startPoint;
	private Point endPoint;
	private JFrame parentFrame;
	private SmartScreenshotController controller;

	public AreaSelectionPanel(JFrame parentFrame, SmartScreenshotController controller) {
		this.parentFrame = parentFrame;
		this.controller = controller;
		setOpaque(false);

		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				startPoint = e.getPoint();
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				endPoint = e.getPoint();
				if (startPoint != null && endPoint != null) {
					int x = Math.min(startPoint.x, endPoint.x);
					int y = Math.min(startPoint.y, endPoint.y);
					int width = Math.abs(endPoint.x - startPoint.x);
					int height = Math.abs(endPoint.y - startPoint.y);

					controller.setScreenshotArea(x, y, width, height);
					parentFrame.dispose();
					controller.setVisible(true);
				}
			}
		});

		addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseDragged(MouseEvent e) {
				endPoint = e.getPoint();
				repaint();
			}
		});
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		if (startPoint != null && endPoint != null) {
			Graphics2D g2d = (Graphics2D) g;
			g2d.setColor(new Color(255, 0, 0, 100));

			int x = Math.min(startPoint.x, endPoint.x);
			int y = Math.min(startPoint.y, endPoint.y);
			int width = Math.abs(endPoint.x - startPoint.x);
			int height = Math.abs(endPoint.y - startPoint.y);

			g2d.fillRect(x, y, width, height);
			g2d.setColor(Color.RED);
			g2d.drawRect(x, y, width, height);
		}
	}
}
